This guide aims to expand on the specification and demonstrate how to utilize
ULAplus from Sinclair BASIC.

The 64 colour mode of the modified ULA is controlled by two ports, #BF3B and
#FF3B, that is 48955 and 65339 in decimal (this guide will use the decimal
values from this point as that is how the value is entered in BASIC).

The first port, 48955, is used to switch the mode on and off, and to select
which palette entry is selected to be read or written on the other port.

The byte written to port 48955 has two parts. The high two bits select the
"register group". Currently there are only two groups, the "palette group" and
the "mode group".

When the "mode group" is selected, the lower bits are ignored. To select the
mode group the bits must be set like this: 0b01xxxxxx, that is the most
significant bit is LOW, the next significant bit is HIGH, and the remaining bits
are ignored.

An example of the Sinclair BASIC instructions needed to activate the 64 colour
mode is as follows:

10 REM select the "mode group" and write 0b00000001 to enable the mode
20 OUT 48955,64
30 OUT 65339,1

Next we need to select a palette entry to change. We select the "palette group"
and write a value to the "palette sub-group" to select the desired entry.

To select the palette group the two most significant bits must be set LOW. If
this is the case, the remaining six bits select the palette entry.

The palette is arranged in four seperate tables, these correspond to the
following attribute values:
   * FLASH = 0 and BRIGHT = 0
   * FLASH = 0 and BRIGHT = 1
   * FLASH = 1 and BRIGHT = 0
   * FLASH = 1 and BRIGHT = 1

Each table has sixteen positions, eight INK colours and eight PAPER colours.
The 64 palette entries and their corresponding attributes are shown in the
following table:

   +------------+----------+----+----+----+----+----+----+----+----+
   |            | Spectrum |    |    |    |    |    |    |    |    |
   |            | colour:  |  0 |  1 |  2 |  3 |  4 |  5 |  6 |  7 |
   +------------+----------+----+----+----+----+----+----+----+----+
   | FLASH off  | INK      |  0 |  1 |  2 |  3 |  4 |  5 |  6 |  7 |
   | BRIGHT off +----------+----+----+----+----+----+----+----+----+
   |            | PAPER    |  8 |  9 | 10 | 11 | 12 | 13 | 14 | 15 |
   +------------+----------+----+----+----+----+----+----+----+----+
   | FLASH off  | INK      | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
   | BRIGHT on  +----------+----+----+----+----+----+----+----+----+
   |            | PAPER    | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
   +------------+----------+----+----+----+----+----+----+----+----+
   | FLASH om   | INK      | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 |
   | BRIGHT off +----------+----+----+----+----+----+----+----+----+
   |            | PAPER    | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 |
   +------------+----------+----+----+----+----+----+----+----+----+
   | FLASH on   | INK      | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 |
   | BRIGHT on  +----------+----+----+----+----+----+----+----+----+
   |            | PAPER    | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 |
   +------------+----------+----+----+----+----+----+----+----+----+

Note1: The Spectrum's BORDER colour is taken from the first paper table.
       That is, palette entries 8 to 15.

Note2: In Timex hi-res mode, the border colour is the BRIGHT 1 paper table.
       That is, palette entries 24 to 31.

After the palette entry to be changed is selected, the byte corresponding to the
desired colour value can be written to port 65339. The intensities of red, green
and blue are encoded as follows:

   * bits 0-1 control the blue intensity (a value between 0 and 3)
   * bits 2-4 control the red intensity (a value between 0 and 7)
   * bits 5-7 control the green intensity (a value between 0 and 7)

The red, green and blue intensities are thus used to generate a single byte
corresponding to one of the 256 possible colour values. After this is written to
the palette all subsequent use of that palette entry (colour and attribute
combination) will appear on the Spectrum display in the new colour.

As an example we will write a value to the palette entry corresponding to
non-FLASHing non-BRIGHT, PAPER 7. This is the PAPER colour that is set when the
Spectrum boots so as soon as we change the palette entry we should immediately
see the background and the BORDER change to the new colour.

    10 REM first our code to turn on the 64 colour mode
    20 OUT 48955,64
    30 OUT 65339,1
    40 REM next we select the desired palette entry
    50 OUT 48955,15
    60 REM we pick a red, green and blue value
    70 LET R=3
    80 LET G=6
    90 LET B=1
   100 REM we calculate the colour byte and write it to the palette
   110 OUT 65339,((G*32)+(R*4)+B)
   120 REM the background should now be a pale green

We can also read from port 65339 to find the value of the colour currently
stored in the palette.

This can be used to detect whether the program is running on an unmodified
Spectrum, or one supporting the ULAplus 64 colour mode. This method is used in
the 64 colour hue cycling demo, the relevant BASIC line is line 70.

After setting the colour of a palette entry the program tests the value of port
65339 using the IN instruction. If the value returned is not the one expected,
the program displays a message that the 64 colour mode is not available and 
returns to BASIC (note, an unmodified Spectrum will return 255 on this port).

The entire source of the hue cycling demo is reproduced below:

     10 OUT 48955,64
     20 OUT 65339,1
     30 OUT 48955,9
     40 OUT 65339,255
     50 OUT 48955,1
     60 OUT 65339,24
     70 IF (IN 65339<>24) THEN PRINT "this program requires a modified";';"ULA
        that supports the new 64";';"colour mode": STOP
     80 OUT 48955,15
   1000 GO SUB 7000
   1010 LET b=0
   1020 LET r=7
   1030 LET green=0
   1040 LET g=0
   1050 FOR h=0 TO 7
   1060 LET g=h
   1070 GO SUB 9000
   1080 NEXT h
   1090 FOR h=0 TO 7
   1100 LET r=7-h
   1110 GO SUB 9000
   1120 NEXT h
   1130 FOR h=0 TO 3
   1140 LET b=h
   1150 GO SUB 9000
   1160 PAUSE 5
   1170 NEXT h
   1180 FOR h=0 TO 7
   1190 LET g=7-h
   1200 GO SUB 9000
   1210 NEXT h
   1220 FOR h=0 TO 7
   1230 LET r=h
   1240 GO SUB 9000
   1250 NEXT h
   1260 FOR h=0 TO 3
   1270 LET b=3-h
   1280 GO SUB 9000
   1290 PAUSE 5
   1300 NEXT h
   1310 GO TO 1010
   7000 PRINT "This program demonstrates the"
   7010 PRINT "ability of the ULAplus palette"
   7020 PRINT "extensions to do simple palette"
   7040 PRINT "animation in Spectrum BASIC"''
   7050 PRINT "This demo cycles the colour of"
   7060 PRINT "the palette entry corresponding"
   7070 PRINT "to the background paper colour,"
   7080 PRINT "grey on the unmodified Spectrum,"
   7090 PRINT "through crudely calculated hue"
   7100 PRINT "values while leaving the ink"
   7110 PRINT "colour of the foreground text"
   7120 PRINT "unchanged."''
   7130 INK 1: PRINT "The text doesn't have to be"
   7140 PRINT "black, in fact it can be any"
   7150 PRINT "colour in the same colour look"
   7160 PRINT "up table"''
   7170 PAPER 1: PRINT "other paper colours aren't being"
   7180 PRINT "cycled so they appear as normal "
   7190 PAPER 7: INK 0
   7200 RETURN
   9000 LET c=(g*32)+(r*4)+b
   9010 OUT 65339,c
   9020 PAUSE 5
   9030 RETURN

All code examples in this guide are public domain and may be used in your own
software as you wish.